home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / xcoral / xcoral.lha / xcoral-1.72 / init_menus.c < prev    next >
C/C++ Source or Header  |  1993-01-23  |  14KB  |  546 lines

  1. /*
  2. ** Copyright 1989, 1992 by Lionel Fournigault
  3. **
  4. ** Permission to use, copy, and distribute for non-commercial purposes,
  5. ** is hereby granted without fee, providing that the above copyright
  6. ** notice appear in all copies and that both the copyright notice and this
  7. ** permission notice appear in supporting documentation.
  8. ** The software may be modified for your own purposes, but modified versions
  9. ** may not be distributed.
  10. ** This software is provided "as is" without any expressed or implied warranty.
  11. **
  12. **
  13. */
  14.  
  15. #include <stdio.h>
  16. #include <X11/Xlib.h>
  17. #include <X11/Xutil.h>
  18. #ifndef apollo
  19. #include <malloc.h>
  20. #endif
  21.  
  22. #include "menus.h"
  23.  
  24. XContext        SwContext;
  25. XContext        TiContext;
  26. static ResourcesMenu    rm;
  27.  
  28. static int getnbstr ();
  29. static char *getmaxstr ();
  30. static void show_bar ();
  31. static VMenu *Vmenu ();
  32.  
  33. extern void Display3D ();
  34.  
  35. /*
  36. **    Function name : InitMenuRes
  37. **
  38. **    Description :  Initialisations des ressources pour les menus.
  39. **        La fonte, le foregreound, le background ainsi que
  40. **        les couleurs utilisees pour le 3D. 
  41. **        Plusieurs contextes graphiques sont mis en oeuvre.
  42. **    
  43. **    Input :  Le display, font, foreground, background, top_shadow et bottom_shadow.
  44. **    Ouput :
  45. */
  46. void InitMenusRes ( display, font, fg, bg, ts, bs )
  47.     Display        *display;
  48.     XFontStruct    *font;
  49.     unsigned long     fg, bg, ts, bs;
  50. {
  51.     GC gc;
  52.     XGCValues gcv;
  53.     unsigned long gcm;
  54.     
  55.     gc = DefaultGC ( display, DefaultScreen (display ));
  56.  
  57.     rm.ngc = XCreateGC ( display, DefaultRootWindow ( display ), 0, &gcv );
  58.     rm.bgc = XCreateGC ( display, DefaultRootWindow ( display ), 0, &gcv );  /* Ne sert plus == ngc */
  59.     rm.ugc = XCreateGC ( display, DefaultRootWindow ( display ), 0, &gcv );
  60.     rm.igc = XCreateGC ( display, DefaultRootWindow ( display ), 0, &gcv );
  61.  
  62.     rm.top_shadow = ts;
  63.     rm.bot_shadow = bs;
  64.     rm.font = font;
  65.     rm.fg = fg;
  66.     rm.bg = bg;
  67.  
  68.     XCopyGC ( display, gc, (~0), rm.ngc );
  69.     XCopyGC ( display, gc, (~0), rm.igc );
  70.     
  71.     gcm = 0;
  72.     gcm |= GCFunction;    gcv.function = GXxor;
  73.     gcm |= GCPlaneMask;    gcv.plane_mask = fg ^ bg;
  74.     gcm |= GCForeground;    gcv.foreground = fg ^ bg;
  75.     gcm |= GCBackground;    gcv.background = bg;
  76.  
  77.     XChangeGC ( display, rm.igc, gcm, &gcv );
  78.     
  79.     gcv.line_width = 0; gcv.font = font -> fid;
  80.     gcv.background = bg; gcv.foreground = fg;
  81.     
  82.     XChangeGC ( display, rm.ngc, GCLineWidth | GCFont | GCForeground |
  83.         GCBackground, &gcv );
  84.  
  85.     XCopyGC ( display, rm.ngc, (~0), rm.bgc );
  86.     XCopyGC ( display, rm.ngc, (~0), rm.ugc );
  87.     
  88.     rm.height_bar = font -> ascent + font -> descent + BAR_SPACE;
  89.  
  90.     TiContext  = XUniqueContext ();
  91.     SwContext = XUniqueContext ();
  92. }
  93.  
  94.  
  95. /*
  96. **    Function name : MakeMenus
  97. **
  98. **    Description : Fabrication des menus pour chacun des titres.
  99. **
  100. **    Input :  Le display, la fenetre parent, les titres, les items et la
  101. **        table des callbacks.
  102. **    Ouput : XYMenu *
  103. */
  104. XYMenu *MakeMenus ( display, w, title, item, fnt ) 
  105.     Display        *display;
  106.     Window        w;
  107.     char        **title;
  108.     char        ***item;
  109.     void        (**fnt []) ();
  110. {
  111.     XYMenu        *menu;
  112.     SWindow        *sw;
  113.     XWindowAttributes att;
  114.     register     int i = 0;
  115.     register     int x, width;
  116.     VMenu        *Vmenu ();
  117. /*    char    *malloc (); */
  118.  
  119.     XGetWindowAttributes ( display, w, &att );
  120.     menu = ( XYMenu * ) malloc ( sizeof ( XYMenu ));
  121.        bzero ( menu, sizeof ( XYMenu ));
  122.    
  123.     menu -> width_relief = DEPTH_WIDTH;
  124.     menu -> font = rm.font;
  125.     menu -> bar_height = rm.height_bar;
  126.     menu -> bar_width     = att.width + ( menu -> width_relief * 2 );
  127.     menu -> h_item = rm.font->ascent + rm.font->descent + 2 + ( 2 * menu -> width_relief );
  128.     menu -> y_menu = menu -> bar_height + 2;        
  129.     menu -> titlename     = title;
  130.     menu -> itemname     = item;
  131.     menu -> y_title = rm.font -> ascent +  1;
  132.     menu -> parent = w;
  133.     menu -> n_last_unmapped = -1;
  134.     menu -> hmax_menu = 0;
  135.     menu -> w_under = w;
  136.     menu -> Ngc = rm.ngc;
  137.     menu -> Igc = rm.igc;
  138.     menu -> Bgc = rm.bgc;
  139.     menu -> Ugc = rm.ugc;
  140.     menu -> top_sh = rm.top_shadow;
  141.     menu -> bot_sh = rm.bot_shadow;
  142.  
  143.     menu -> fg_bar = menu -> fg_menu = rm.fg;
  144.     menu -> bg_bar = menu -> bg_menu = rm.bg;
  145.  
  146.     menu -> w_bar = XCreateSimpleWindow ( display, w, 0, 0, menu -> bar_width,
  147.         menu -> bar_height, 0, rm.bg, rm.bg );
  148.     XSelectInput ( display, menu->w_bar, ExposureMask | StructureNotifyMask
  149.         | VisibilityChangeMask );
  150.  
  151.     menu->mapped = 0;
  152.     menu -> save = 0;
  153.     x = 2;
  154.     while ( *title != 0 ) {
  155.         width = XTextWidth ( rm.font, *title, strlen ( *title )) + 20;
  156.         *title++;    
  157.         menu->w_title [i] =
  158.             XCreateSimpleWindow ( display, menu->w_bar, x, 2,
  159.                 width,
  160.                 menu -> h_item,
  161.                 0, rm.bg, rm.bg );
  162.         menu->title_width [i] = width;
  163.         /*
  164.          * Ne sert que pour savoir si on est dans la barre des titres.
  165.          * le choix de width n'a pas d'importance.
  166.          */
  167.         XSaveContext ( display, menu->w_title [i], TiContext, (caddr_t) width ) ;
  168.  
  169.         XSelectInput ( display, menu->w_title [i], ExposureMask |
  170.             EnterWindowMask | ButtonPressMask );
  171.         menu -> no_menu = i;        
  172.         sw = ( SWindow * ) malloc ( sizeof ( SWindow ));
  173.         sw -> w = menu -> w_title [i];
  174.         sw -> type = MENU;
  175.         sw -> no_m = i;
  176.         sw -> no_i = 0;
  177.         if ( XSaveContext ( display, sw -> w, SwContext, (caddr_t) sw ) != 0 )
  178.             (void) fprintf ( stderr, "make_xymenus XSaveContext Error\n" );
  179.         menu->vmenu [i] = Vmenu ( display, w, menu, *item, x, *fnt, rm.bg ); 
  180.         if ( menu -> vmenu [i] -> height > menu -> hmax_menu )
  181.             menu -> hmax_menu = menu -> vmenu [i] -> height;
  182.         x += width;
  183.         i++;
  184.         *item++;
  185.         *fnt++;
  186.         if ( i > 10 )
  187.             break;
  188.     }
  189.     menu->nb_menus = i;
  190.     if ( DoesSaveUnders ( DefaultScreenOfDisplay ( display ) ) != True )
  191.         SetMenuPixmap ( display, menu, menu -> bar_width );
  192.     show_bar ( display, menu -> parent, menu );
  193.     return menu;
  194. }
  195.  
  196.  
  197. /*
  198. **    Function name : MouseInMenuBar
  199. **
  200. **    Description :  Comme son nom l'indique.
  201. **
  202. **    Input : Le Display, la fenetre
  203. **    Ouput : Vrai ou Faux.
  204. */
  205. int MouseInMenuBar ( display, w )
  206.     Display *display;
  207.     Window w;
  208. {
  209.     int m;
  210.  
  211.     if ( XFindContext ( display, w, TiContext, (caddr_t *) &m ) != XCNOENT )
  212.         return True;
  213.     else
  214.         return False;
  215. }
  216.  
  217.  
  218. /*
  219. **    Function name : SetMenuPixmap
  220. **
  221. **    Description : Fabrication d'un pixmap pour sauvegarder
  222. **        les parties cachees.
  223. **    Input : Le display, le menu, largeur de la fenetre parent.
  224. **    Ouput :
  225. */
  226. void SetMenuPixmap ( display, menu, width )
  227.     Display *display;
  228.     XYMenu *menu;
  229.     register int width;
  230. {
  231.  
  232.     if ( menu -> save != 0 ) {
  233. #ifdef DEBUG
  234.         fprintf ( stderr, "Pixmap ms = %d\n", menu -> save );
  235. #endif
  236.             XFreePixmap ( display, menu -> save );
  237.     }
  238.  
  239. #ifdef SHADOW
  240.     menu -> save = XCreatePixmap ( display,
  241.         menu -> w_under , width,
  242.         menu -> hmax_menu + SHAD + 10,
  243.         DefaultDepth ( display, DefaultScreen ( display )));
  244. #else
  245.     menu -> save = XCreatePixmap ( display,
  246.         menu -> w_under , width,
  247.         menu -> hmax_menu + 10,
  248.         DefaultDepth ( display, DefaultScreen ( display )));
  249. #endif
  250.     menu -> save_ok = 0;        /* Ya rien  dans la pixmap */
  251.     menu -> pix_width = width;
  252. }
  253.  
  254.  
  255. /*
  256. **    Function name : Vmenu
  257. **
  258. **    Description : Fabrication des menus associes a chaque titre
  259. **        principal.
  260. **
  261. **    Input :  Le Display, la fenetre parent, menu, table des items,
  262. **        la fonte, le background.
  263. **    Ouput :
  264. */
  265. static VMenu *Vmenu ( display, window, menu, item, x_title, fnt, bg )
  266.     Display    *display;
  267.     Window    window;
  268.     XYMenu    *menu;
  269.     register char **item;
  270.     register int x_title;
  271.     void (**fnt) ();
  272.     unsigned long bg;
  273. {
  274.     VMenu    *vm;
  275.     SWindow    *sw;
  276.     char    *getmaxstr ();
  277.     XSetWindowAttributes att, att_io;
  278.     register int x_menu, n;
  279.     register char *maxstr;
  280.     register int nb_item;
  281.  
  282.     vm = ( VMenu * ) malloc ( sizeof ( VMenu ));
  283.        bzero ( vm, sizeof ( VMenu ));
  284.     maxstr = getmaxstr ( item );
  285.     nb_item = getnbstr ( item );
  286.  
  287.     vm -> height = ( nb_item * menu -> h_item ) + 6;
  288.     vm -> width = XTextWidth ( menu->font, maxstr, strlen ( maxstr )) + 26
  289.         + ( 2 * menu -> width_relief );
  290.  
  291.     x_menu = x_title;    
  292.     vm -> x = x_menu;
  293. #ifdef SHADOW
  294.     att_io.win_gravity = NorthWestGravity;
  295.     att_io.event_mask = 0;
  296.     att_io.override_redirect = False;
  297.     att_io.do_not_propagate_mask = NoEventMask;
  298.     att_io.cursor = None;
  299.     vm -> trans = XCreateWindow ( display, window, x_menu, menu -> y_menu,
  300.         vm -> width + SHAD, vm -> height + SHAD, 0, 0,
  301.         InputOutput, CopyFromParent,
  302.         CWWinGravity | CWEventMask | CWOverrideRedirect | 
  303.         CWDontPropagate | CWCursor, 
  304.         &att_io );
  305.     vm -> shadow = XCreateSimpleWindow ( display, vm -> trans, SHAD,
  306.             SHAD, vm->width, vm->height, 0, 
  307.             BlackPixel ( display, DefaultScreen ( display )),
  308.             BlackPixel ( display, DefaultScreen ( display )));
  309.     vm -> v_frame = XCreateSimpleWindow ( display, vm -> trans, 0,
  310.             0, vm->width, vm->height, 0, bg, bg );
  311.     XSelectInput ( display, vm->v_frame, ExposureMask | LeaveWindowMask );
  312.     XSelectInput ( display, vm -> trans, ExposureMask | LeaveWindowMask );
  313. #else
  314.     vm->v_frame = XCreateSimpleWindow ( display, window, x_menu,
  315.             menu->y_menu, vm->width, vm->height, 0, bg, bg );
  316.     XSelectInput ( display, vm->v_frame, ExposureMask | LeaveWindowMask );
  317. #endif
  318.     if ( DoesSaveUnders ( DefaultScreenOfDisplay ( display ) ) == True )
  319.         att.save_under = True;
  320.     else
  321.         att.save_under = False;
  322. #ifdef SHADOW
  323.     XChangeWindowAttributes ( display, vm -> trans, CWSaveUnder, &att );
  324. #else
  325.     XChangeWindowAttributes ( display, vm->v_frame, CWSaveUnder, &att );
  326. #endif
  327.     n = 0;
  328.     vm -> iname = item;
  329.     while ( *item != 0 ) {
  330.         vm->w_item [n] = XCreateSimpleWindow ( display, vm->v_frame,
  331.             3, (n * menu -> h_item) + 3,
  332.             vm->width - 6, menu -> h_item, 0,
  333.             bg, bg );
  334.         XSelectInput ( display, vm->w_item [n], ExposureMask
  335.             | EnterWindowMask );
  336.         sw = ( SWindow * ) malloc ( sizeof ( SWindow ));
  337.         sw -> w = vm->w_item [n];
  338.         sw -> type = ITEM;
  339.         sw -> no_i = n;
  340.         sw -> no_m = menu -> no_menu;
  341.         if ( XSaveContext ( display, sw -> w, SwContext, (caddr_t) sw ) != 0 )
  342.             (void) fprintf ( stderr,  "make_vertical_menus XSaveContext Error\n" );
  343.         vm -> func [n] = *fnt;
  344.         n++;
  345.         *item++;
  346.         *fnt++;
  347.     }
  348. #ifdef SHADOW
  349.     XMapSubwindows ( display, vm -> trans );
  350.     XMapSubwindows ( display, vm -> v_frame );
  351. #else
  352.     XMapSubwindows ( display, vm -> v_frame );
  353. #endif
  354.     vm->nb_items = n;
  355.     return ( vm );
  356. }
  357.  
  358.  
  359. /*
  360. **    Function name : SetHiddenWindow
  361. **
  362. **    Description : Initialise les parametres de la fenetre cachee.
  363. **
  364. **    Input : Le menu, la fenetre cachee, le contexte graphique.
  365. **    Ouput :
  366. */
  367. void SetHiddenWindow ( menu, w, gc )
  368.     XYMenu    *menu;
  369.     Window    w;
  370.     GC    gc;
  371. {
  372.     menu -> w_under = w;
  373.     menu -> Ugc = gc;
  374. }
  375.  
  376.  
  377. /*
  378. **    Function name : getnbstr
  379. **
  380. **    Description : Pour avoir la taille d'un tableau de pointeurs
  381. **
  382. **    Input : La tableau.
  383. **    Ouput : le nombre d'entree non vide dans le tableau.
  384. */
  385. static int getnbstr ( tstr )
  386.     register char **tstr;
  387. {
  388.     register int i = 0;
  389.     while ( *tstr != 0 ) {
  390.         i++;
  391.         *tstr++;
  392.         if ( i > 100 ) return ( 0 );
  393.     }
  394.     return ( i );
  395. }
  396.  
  397.  
  398. /*
  399. **    Function name : getmaxstr
  400. **
  401. **    Description : Donne la plus longue chaine dans un tableau,
  402. **        en fonction de la fonte utilisee.
  403. **
  404. **    Input : Le tableau
  405. **    Ouput : La plus grande chaine.
  406. */
  407. static char *getmaxstr ( tstr )
  408.     register char **tstr;
  409. {
  410.     register char *s;
  411.     register int i, j;
  412.  
  413.     i = 0;
  414.     while ( *tstr != 0 ) {
  415.         j = strlen ( *tstr );
  416.            if ( (j=XTextWidth ( rm.font, *tstr, strlen ( *tstr ))) > i ) {
  417.             s = *tstr;
  418.             i = j;
  419.         }
  420.         tstr ++;
  421.     }
  422.     return ( s );
  423. }
  424.  
  425.  
  426. /*
  427. **    Function name : RefreshMenuBar
  428. **
  429. **    Description : Redessine la barre des titres.
  430. **
  431. **    Input : Le display, le menu.
  432. **    Ouput :
  433. */
  434. void RefreshMenuBar ( display, menu )
  435.     Display     *display;
  436.     XYMenu    *menu;
  437. {
  438.     register int i;
  439.     register char     **str = menu->titlename;
  440.  
  441.     XResizeWindow ( display, menu -> w_bar, menu -> bar_width,
  442.         menu -> bar_height );
  443.  
  444.     Display3D ( display, menu -> w_bar,
  445.             menu -> top_sh, menu -> bot_sh,
  446.             menu -> width_relief , DEPTH_UP );
  447.  
  448.     for ( i=0; i < menu->nb_menus; i++ ) {
  449.         XDrawString ( display, menu->w_title [i], menu -> Bgc, 10,
  450.             menu -> y_title + menu -> width_relief + 1,
  451.             *str, strlen ( *str ));
  452.         str++;
  453.     }
  454. }
  455.  
  456.  
  457. /*
  458. **    Function name : show_bar
  459. **
  460. **    Description : Affichage de la barre des titres.
  461. **
  462. **    Input : Le display, la fenetre mere, le menu.
  463. **    Ouput :
  464. */
  465. static void show_bar ( display, w, menu )
  466.     Display    *display;
  467.     Window    w;
  468.     XYMenu    *menu;
  469. {
  470.     XEvent    event;
  471.  
  472.     XMapSubwindows ( display, menu->w_bar ); 
  473.     XMapWindow ( display, menu->w_bar ); 
  474.     XMapWindow ( display, w );
  475.     XFlush ( display );
  476.     XWindowEvent ( display, w, ExposureMask, &event );
  477.     XWindowEvent ( display, menu -> w_bar, ExposureMask, &event );
  478.     RefreshMenuBar ( display, menu );
  479. }
  480.  
  481.  
  482. /*
  483. **    Function name : ButtonPressInMenu
  484. **
  485. **    Description : Comme son nom l'indique.
  486. **
  487. **    Input : La fenetre de l'evenement, le menu.
  488. **    Ouput : Le numero du menu, sinon -1;
  489. */
  490. int ButtonPressInMenu ( w, menu )
  491.     Window    w;
  492.     XYMenu    *menu;
  493. {
  494.     register int i, n = -1;
  495.  
  496.     for ( i=0; i < menu -> nb_menus; i++) 
  497.         if ( w == menu -> w_title [i] ) {
  498.             n = i;
  499.             break;
  500.         }
  501.     return ( n );
  502. }
  503.  
  504.  
  505. /*
  506. **    Function name : DeleteMenu
  507. **
  508. **    Description : Comme son nom l'indique.
  509. **
  510. **    Input : Le display, le menu.
  511. **    Ouput :
  512. */
  513. void DeleteMenu ( display, menu )
  514. Display    *display;
  515. XYMenu    *menu;
  516. {
  517.     register int i, j;
  518.     SWindow    *sw;
  519.  
  520.     for ( i = 0; i < menu -> nb_menus; i++ ) {
  521.         for ( j=0; j < menu -> vmenu [i] -> nb_items; j++ ) {
  522.             XFindContext ( display, menu -> vmenu [i] -> w_item [j], SwContext, (caddr_t *) &sw );
  523.                      if ( sw != 0 )
  524.                 (void) free (( char * ) sw );
  525.             XDeleteContext ( display, menu -> vmenu [i] -> w_item [j], SwContext );
  526.             XDestroyWindow ( display, menu -> vmenu [i] -> w_item [j] ); 
  527.         }
  528. #ifdef SHADOW
  529.         XDestroyWindow ( display, menu -> vmenu [i] -> trans );
  530. #else
  531.         XDestroyWindow ( display, menu -> vmenu [i] -> v_frame );
  532. #endif
  533.         XFindContext ( display, menu -> w_title [i], SwContext, (caddr_t *) &sw );
  534.         if ( sw != 0 )
  535.             (void) free ( ( char * ) sw );
  536.         XDeleteContext ( display, menu -> w_title [i], SwContext );
  537.         if ( menu -> vmenu [i] != 0 )
  538.             free ( ( char * ) menu -> vmenu [i] );
  539.     }
  540.     XDestroyWindow ( display,menu -> w_bar );
  541.     if ( DoesSaveUnders ( DefaultScreenOfDisplay ( display ) ) != True )
  542.         XFreePixmap ( display, menu -> save );
  543.     if ( menu != 0 )
  544.         (void) free ( ( char * ) menu ); 
  545. }
  546.